#include <assert.h>

#include "c_List.h"

sfx::c_ListElem* sfx::c_ListElem::getLastObj(void)
{
   c_ListElem * Obj;
   c_ListElem * Cur;

   Obj = this;
   while ((Cur = Obj->getNextObj()) != 0)
   {
      Obj = Cur;
   }
   return Obj;
}

sfx::c_ListElem* sfx::c_ListElem::getFirstObj(void)
{
   c_ListElem * Obj;
   c_ListElem * Cur;

   Obj = this;
   while ((Cur = Obj->getPrevObj()) != 0)
   {
      Obj = Cur;
   }
   return Obj;
}

sfx::e_ErrorCode sfx::c_ListElem::joinList(c_ListElem *  Obj)
{
   c_ListElem * Tail;
   c_ListElem * Head;

   if (Obj == 0)
   {
      return d_BadParameters;
   }

   Tail = getLastObj();
   Head = Obj->getFirstObj();

   Tail->setNextObj(Head);
   Head->setPrevObj(Tail);

   return d_Success;
}

unsigned sfx::c_ListElem::getNumObjInList(void)
{
   unsigned   Cnt(0);
   c_ListElem * Obj;

   Obj = getFirstObj();
   while (Obj != 0)
   {
      Cnt++;
      Obj = Obj->getNextObj();
   }
   return Cnt;
}

sfx::e_ErrorCode sfx::c_ListElem::insertObj(c_ListElem *PrevObj, c_ListElem *NextObj)
{
   assert(m_ObjOwner == 0);

   if( getPrevObj() || getNextObj() )
   {
      return(d_Failed);
   }

   if(PrevObj)
   {
      PrevObj->setNextObj(this);
   }

   setPrevObj(PrevObj);

   if(NextObj)
   {
      NextObj->setPrevObj(this);
   }

   setNextObj(NextObj);


   return(d_Success);
}

sfx::e_ErrorCode sfx::c_ListElem::insertObjBefore(c_ListElem *InsertObj)
{
   c_ListElem *ObjPrev;
   c_ListElem *ObjNext;

   if(!InsertObj)
   {
      return(d_BadAdress);
   }

   ObjNext = this;
   ObjPrev = getPrevObj();

   return(InsertObj->insertObj(ObjPrev, ObjNext));
}

sfx::e_ErrorCode sfx::c_ListElem::insertObjAfter(c_ListElem *InsertObj)
{
   c_ListElem *ObjPrev;
   c_ListElem *ObjNext;

   if(!InsertObj)
   {
      return(d_BadAdress);
   }

   ObjPrev = this;
   ObjNext = getNextObj();

   return(InsertObj->insertObj(ObjPrev, ObjNext));
}

sfx::c_ListElem* sfx::c_ListElem::removeObjsBetween(c_ListElem *EndObj)
{
   c_ListElem *FirstObj, *LastObj;

   if(!EndObj)
   {
      return(0);
   }

   FirstObj = getNextObj();

   if(FirstObj == EndObj)
   {
      return(0);
   }

   LastObj  = EndObj->getPrevObj();

   FirstObj->setPrevObj(0);
   LastObj->setNextObj(0);

   this->setNextObj(EndObj);
   EndObj->setPrevObj(this);

   return(FirstObj);
}

sfx::c_ListElem* sfx::c_ListElem::removeObj(void)
{
   c_ListElem *PrevObj = getPrevObj();
   c_ListElem *NextObj = getNextObj();

   assert(m_ObjOwner == 0);

   if (PrevObj)
   {
      setPrevObj(0);
      PrevObj->setNextObj(NextObj);
   }

   if (NextObj)
   {
      setNextObj(0);
      NextObj->setPrevObj(PrevObj);
   }

   return(NextObj);
}
